//-----------------------------------------------------------------------
// <copyright file="TaskBase.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Provides a common task for all the SDC Build Tasks.</summary>
//-----------------------------------------------------------------------
namespace Microsoft.Sdc.Tasks
{
    using System;
    using Microsoft.Build.Utilities;

    /// <summary>
    /// Provides a common task for all the SDC Build Tasks.
    /// </summary>

    public abstract class TaskBase : Task
    {
        private Utilities utilities;

        /// <summary>
        /// Initializes a new instance of the TaskBase class.
        /// </summary>
        protected TaskBase()
        {
            TaskResources = Resources.GetResourceManager();
            this.utilities = new Utilities(this, TaskResources);
        }

        /// <summary>
        /// A helper Utilities class.
        /// </summary>
        /// <value></value>
        internal Utilities Utilities
        {
            get { return this.utilities; }
        }        

        /// <summary>
        /// Main execute method. Handles bubbled up exceptions and will log the errors along
        /// with all the public properties of the task.
        /// </summary>
        /// <remarks>
        /// This class is sealed to prevent accidental implementations based on the previous pattern.
        /// Instead subclasses should implement the InternalExecute method.
        /// </remarks>
        /// <returns>true on success</returns>
        public override sealed bool Execute()
        {
            try
            {
                // so if we haven't been given a BuildEngine already then use the internal one here
                // this way people can call the tasks standalone esp. useful from tests

                if (base.BuildEngine == null)
                {
                    base.BuildEngine = new PseudoBuildEngine();
                }

                this.InternalExecute();
                return true;
            }

            catch (TaskException taskException)
            {
                try
                {
                    Log.LogError(Utilities.CreateExceptionInformation(taskException));
                }
                catch (Exception ex)
                {
                    if (ex.Message == TaskResources.GetString("PseudoEngineException"))
                    {
                        Log.LogError("");
                    }
                    else
                    {
                        Log.LogErrorFromException(ex, true);
                    }
                }
                return false;
            }
            catch (Exception e)
            {
                // Wrap the exception as an InnerException, add some 
                // information about the public properties and bubble it up             
                try
                {
                    Log.LogError(Utilities.CreateExceptionInformation(e));
                }
                catch (Exception ex)
                {
                    Log.LogErrorFromException(ex, true);
                }
                return false;
            }
        }

        /// <summary>
        /// This is the main execute method that all tasks should implement
        /// </summary>
        /// <remarks>
        /// TaskException should be thrown in the event of errors
        /// </remarks>
        protected abstract void InternalExecute();
    }
}

